<template>
  <div>
    <el-card>
      <CategoryList :disabled="!isShowList"></CategoryList>
    </el-card>
    <el-card v-show="isShowList">
      <el-button
        style="margin-bottom: 20px"
        type="primary"
        :icon="Plus"
        @click="addAttr"
        :disabled="!category3Id"
        v-has="`btn.Attr.add`">
        添加属性
      </el-button>
      <el-table :data="AttrList" border>
        <el-table-column
          type="index"
          label="序号"
          align="center"
          width="80px" />
        <el-table-column prop="attrName" label="属性名称" width="180px" />
        <el-table-column label="属性值列表">
          <template v-slot="{ row }">
            <el-tag
              v-for="value in row.attrValueList"
              :key="value.id"
              style="margin-right: 5px">
              {{ value.valueName }}
            </el-tag>
          </template>
        </el-table-column>
        <el-table-column label="操作" width="180px">
          <template v-slot="{ row, $index }">
            <el-button
              :icon="Edit"
              size="small"
              type="primary"
              @click="updateAttr(row)"
              v-has="'btn.Attr.update'"></el-button>

            <el-popconfirm
              :title="`确认删除${row.attrName}?`"
              @confirm="remove(row.id)">
              <template #reference>
                <el-button
                  :icon="Delete"
                  size="small"
                  type="danger"
                  v-has="'btn.Attr.remove'"></el-button>
              </template>
            </el-popconfirm>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <el-card v-show="!isShowList">
      <span style="margin-right: 20px">属性名</span>
      <el-input
        v-model="Attr.attrName"
        placeholder="请输入属性名"
        style="width: 200px"></el-input>

      <div style="margin: 20px 0">
        <el-button type="primary" :icon="Plus" @click="addAttrValue">
          添加属性值
        </el-button>
        <el-button @click="isShowList = true">取消</el-button>
      </div>

      <el-table :data="Attr.attrValueList">
        <el-table-column
          type="index"
          label="序号"
          width="80px"></el-table-column>
        <el-table-column label="属性值名称">
          <template #default="{ row, $index }">
            <el-input
              ref="inputRef"
              v-if="row.isEdit"
              v-model="row.valueName"
              @blur="toShow(row, $index)"></el-input>
            <span
              v-else
              @click="toEdit(row)"
              style="display: inline-block; width: 100%">
              {{ row.valueName }}
            </span>
          </template>
        </el-table-column>
        <el-table-column label="操作">
          <template v-slot="{ row, $index }">
            <el-button
              type="danger"
              :icon="Delete"
              size="small"
              @click="Attr.attrValueList.splice($index, 1)"></el-button>
          </template>
        </el-table-column>
      </el-table>
      <div style="margin: 20px 0">
        <el-button type="primary" @click="SaveAttr" :disabled="isSaveDisabled">
          保存
        </el-button>
        <el-button @click="isShowList = true">取消</el-button>
      </div>
    </el-card>
  </div>
</template>

<script lang="ts">
import { defineComponent } from "vue";
import {
  DeleteAttrApi,
  GetAttrsListApi,
  SaveAttrApi,
} from "@/api/product/attr";
import { ElMessage, type ElInput } from "element-plus";
import lodash, { remove } from "lodash";

export default defineComponent({
  name: "Attr",
});
</script>

<script setup lang="ts">
import type {
  AttrListModel,
  AttrModel,
  AttrValueModel,
} from "@/api/product/model/attrsModel";

import { Plus, Delete, Edit } from "@element-plus/icons-vue";
import { computed, nextTick, ref, watch } from "vue";
import categoryStore from "@/stores/category";

import { storeToRefs } from "pinia";

const isSaveDisabled = computed(() => {
  // 只有指定属性名及至少有一个属性值(必须有属性值名称)
  const hasName = !!Attr.value.attrName;
  // 判断属性值列表中是否至少有一个有属性值名称
  const hasAttrValue = Attr.value.attrValueList.some(
    (value) => value.valueName
  );

  // 如果没有属性名或者没有属性值都是禁用的, 返回true
  return !hasName || !hasAttrValue;
});

const AttrList = ref<AttrListModel>([]);

const { category1Id, category2Id, category3Id } = storeToRefs(categoryStore());

// 获取属性列表的请求
const GetAttrsList = async () => {
  AttrList.value = await GetAttrsListApi({
    category1Id: category1Id.value as number,
    category2Id: category2Id.value as number,
    category3Id: category3Id.value as number,
  });
};

// 侦听3Id发送请求 获取属性列表
watch(category3Id, async (val) => {
  // 当存在category3Id 的时候发请求 获取平台属性列表
  // 不存在的时候清空
  if (val) {
    GetAttrsList();
  } else {
    AttrList.value = [];
  }
});

// 控制列表的显示与隐藏
const isShowList = ref(true);

// 创建一个空的属性对象
const initAttr = () => ({
  attrName: "",
  attrValueList: [],
  categoryId: 0,
  categoryLevel: 3,
});

// 初始化一个属性对象
const Attr = ref<AttrModel>(initAttr());
console.log(Attr.value);

// 点击新增属性
const addAttr = () => {
  Object.assign(Attr.value, initAttr());
  isShowList.value = false;
};

// 点击修改属性
const updateAttr = (row: AttrModel) => {
  // Object.assign把第二个对象的值 赋给 第一个对象
  // Object.assign(Attr.value, row);

  // 解决取消保存时 前面的属性值跟着改变
  Object.assign(Attr.value, lodash.cloneDeep(row));
  // console.log(Attr);
  isShowList.value = false;
};

// 编辑与查看属性值
const inputRef = ref<InstanceType<typeof ElInput>>();
const toEdit = (row: AttrValueModel) => {
  row.isEdit = true;

  nextTick(() => {
    // 使用断言
    // (inputRef.value as HTMLInputElement)?.focus();
    inputRef.value?.focus();
  });
};
const toShow = (row: AttrValueModel, index: number) => {
  // 判断为空的属性值的话 清理掉数据
  if (!row.valueName) {
    Attr.value.attrValueList.splice(index, 1);
    return;
  }
  /*  const isRepeat =
    Attr.value.attrValueList.filter((item) => item.valueName === row.valueName)
      .length === 2; */

  // 方式二: 如果除了自己外, 还有一个的valueName等于row.valueName, 就重名了
  const isRepeat = Attr.value.attrValueList.some(
    (item) => item != row && item.valueName === row.valueName
  );

  // 判断为重复的属性值的话 清理掉数据
  if (isRepeat) {
    Attr.value.attrValueList.splice(index, 1);
    return;
  }

  row.isEdit = false;
};

// 创建一个属性值对象
const AttrValue = <AttrValueModel>() => {
  return {
    valueName: "",
    attrId: Attr.value.id,
    isEdit: true,
  };
};
// 点击添加属性值
const addAttrValue = () => {
  // 添加属性值对象到属性值数组中
  Attr.value.attrValueList.push(AttrValue());

  // 自动获取焦点
  nextTick(() => {
    inputRef.value?.focus();
  });
};

// 点击保存 完成属性的添加
const SaveAttr = async () => {
  Attr.value.categoryId = category3Id as unknown as number;

  // 对要提交的数据进行特定处理/整理操作(开发经常做)
  // 处理1: 过滤掉没有属性值名称的属性值对象
  // 处理2: 删除属性值对象中的edit属性
  Attr.value.attrValueList = Attr.value.attrValueList.filter((value) => {
    if (value.valueName) {
      delete value.isEdit;
      return true;
    }
    return false;
  });
  // 发请求
  await SaveAttrApi(Attr.value);
  // 提示
  ElMessage.success("保存成功");
  isShowList.value = true;
  GetAttrsList();
};

// 删除
const remove = async (id: number) => {
  // 调用删除的请求API
  await DeleteAttrApi(id);
  // 提示删除成功
  ElMessage.success("删除成功");
  // 重新请求列表
  GetAttrsList();
};
</script>

<style scoped lang="scss"></style>
